#define  KANG_BIGENDIAN 1

#define  KANG_ENDIAN KANG_BIGENDIAN
typedef long int32;
typedef short int16;
typedef char int8;

typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;


namespace ByteConverter
{
	template<size_t T>
	inline void convert(char *val)
	{
		std::swap(*val, *(val + T - 1));
		convert<T - 2>(val + 1);
	}

	template<> inline void convert<0>(char *) {}
	template<> inline void convert<1>(char *) {}            // ignore central byte

	template<typename T>
	inline void apply(T *val)
	{
		convert<sizeof(T)>((char *)(val));
	}
}

#if KANG_ENDIAN == KANG_BIGENDIAN
template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); }
template<typename T> inline void EndianConvertReverse(T&) { }
#else
template<typename T> inline void EndianConvert(T&) { }
template<typename T> inline void EndianConvertReverse(T& val) { ByteConverter::apply<T>(&val); }
#endif

template<typename T> void EndianConvert(T*);         // will generate link error
template<typename T> void EndianConvertReverse(T*);  // will generate link error

inline void EndianConvert(uint8&) { }
inline void EndianConvert(int8&)  { }
inline void EndianConvertReverse(uint8&) { }
inline void EndianConvertReverse( int8&) { }


// namespace talk_base
class ByteBuffer{
public:
	ByteBuffer(const std::string& datas){
		_len = datas.size();
		_storage = new byte[_len];
		memcpy(_storage,datas.data(),_len);
		_pos = 0;
	}
	ByteBuffer(size_t length):_pos(0),_len(length),_storage(new byte[length]){

	}
	template <typename T> ByteBuffer &operator>>(T& t){
		t = read<T>();
		return *this;
	}

	template <typename T> ByteBuffer &operator<<(T t){
		EndianConvert(t);
		size_t size = sizeof(T);
		memcpy(&_storage[_pos], (uint8 *)&t, size);
		_pos += size;
		return *this;				
	}
	ByteBuffer &operator<<(std::string t){
		size_t size = t.size();
		memcpy(&_storage[_pos], t.data(), size);
		_pos += size;
		return *this;				
	}
	template <typename T> T read()
	{
		T t = *((T const*)&_storage[_pos]);
		EndianConvert(t); 
		_pos += sizeof(T);
		return t;
	}
// 	template <typename T> ByteBuffer& write(T t)
// 	{
// 
// 	}
	const byte* c_str()const {
		return _storage;
	}
	void pos(int pos){
		_pos = pos;
	}
	size_t remain(){
		return _len - _pos;
	}
	size_t length(){
		return _len;
	}
	byte* data(){
		return _storage;
	}
	~ByteBuffer(){
		delete []_storage;
	}

	std::string readUTF(){
		short len = read<short>();
		std::string str(&_storage[_pos],len);
		_pos+=len;
		return str;
	}
private:
	size_t _pos;
	byte* _storage;
	size_t _len;
};